﻿Imports System.IO
Imports System.Text
Imports System.ServiceModel

Public Class frmXMLStamp
    Private _random As Random
    Private token As String
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetToken.Click
        Dim transactionID As Long = _random.[Next]()
        Dim [Error] As String
        Dim Util As New Utilerias()
        [Error] = Util.CreateToken(Utilerias.RFC, transactionID, token)
        If Not String.IsNullOrEmpty([Error]) Then
            ShowUnknownError([Error])
            Return
        End If
        ShowResult(String.Format("Token: {0}", token))
    End Sub

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        _random = New Random()
        token = String.Empty

    End Sub

    Private Sub btnSelectDirectory_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectDirectory.Click
        FolderBrowserDialog.ShowNewFolderButton = False
        FolderBrowserDialog.RootFolder = System.Environment.SpecialFolder.MyComputer
        Dim result As DialogResult = Me.FolderBrowserDialog.ShowDialog()
        If result = DialogResult.OK Then
            lstSource.Items.Clear()
            lstDestination.Items.Clear()
            Dim foldername As String = Me.FolderBrowserDialog.SelectedPath
            For Each file As String In Directory.GetFiles(foldername)
                If Path.GetExtension(file).ToUpper() = ".XML" Then
                    lstSource.Items.Add(file)
                End If
            Next
        End If
    End Sub

    Private Sub btnStampInvoices_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStampInvoices.Click
        Dim transactionID As Long = _random.[Next]()

        Dim Certificado As String = String.Empty
        Dim noCertificado As String = String.Empty
        Dim contador As Int16 = 0
        Dim Util As New Utilerias()
        ToolStripProgressBar.Maximum = lstSource.SelectedItems.Count
        ToolStripProgressBar.Value = 0
        For Each fileName As [String] In lstSource.SelectedItems
            transactionID = _random.[Next]()
            Dim bError As Boolean = False
            Do
                If contador > 2 Then
                    bError = True
                Else
                    Dim invoiceXML = New SrvTimbrado.ComprobanteXML()
                    Using myFile As New StreamReader(fileName)
                        invoiceXML.DatosXML = myFile.ReadToEnd()
                    End Using

                    Try
                        If (invoiceXML.DatosXML.Contains("retenciones:Retenciones")) Then
                            invoiceXML.DatosXML = retenciones(invoiceXML.DatosXML)
                        Else
                            invoiceXML.DatosXML = cfdiComprobante(invoiceXML.DatosXML)
                        End If


                        Using TimbradoSrv = New SrvTimbrado.TimbradoClient()
                            Dim advertencias = TimbradoSrv.TimbraXML(invoiceXML, Utilerias.RFC, token, transactionID)

                            Dim lsName As New StringBuilder(Path.GetFileName(fileName))
                            Dim lsDir As New StringBuilder(Path.GetDirectoryName(fileName))
                            Dim lsExt As New StringBuilder(Path.GetExtension(fileName).ToUpper())
                            Dim lsOutputFile As New StringBuilder(String.Format("{0}\{1}{2}{3}", lsDir, lsName, transactionID, lsExt.ToString()))
                            Dim loXML As New StringBuilder()
                            loXML.Append(invoiceXML.DatosXML)
                            Using loSW As New StreamWriter(lsOutputFile.ToString(), False, Encoding.UTF8)
                                loSW.Write(loXML.ToString())
                            End Using
                            ToolStripProgressBar.PerformStep()
                            contador = 0
                            bError = False
                            lstDestination.Items.Add(lsOutputFile.ToString())
                        End Using
                    Catch serviceFault As FaultException(Of SrvTimbrado.FallaServicio)
                        Using errorForm = New frmError(TranslateFault.ToServiceError(serviceFault.Detail))
                            errorForm.ShowDialog()
                        End Using
                        bError = True
                    Catch sessionFauld As FaultException(Of SrvTimbrado.FallaSesion)
                        If sessionFauld.Detail.Descripcion.Contains("El Token no es valido o ya expiro") Then
                            Util.CreateToken(Utilerias.RFC, transactionID, token)
                            contador += 1
                        End If
                        ShowSessionError(TranslateFault.ToSessionError(sessionFauld.Detail))
                    Catch validationFault As FaultException(Of SrvTimbrado.FallaValidacion)
                        Using errorForm = New frmError(TranslateFault.ToValidationError(validationFault.Detail))
                            errorForm.ShowDialog()
                        End Using
                        bError = True
                    End Try
                End If
                If bError Then
                    contador = 0
                End If
            Loop While contador > 0
        Next
    End Sub
    Public Sub ShowResult(ByVal message As String)
        MessageBox.Show([String].Format("{0}", message), "Ecodex UniTest")
    End Sub
    Public Sub ShowUnknownError(ByVal message As String)
        MessageBox.Show([String].Format("Error: {0}", message), "Ecodex UniTest")
    End Sub
    Public Sub ShowSessionError(ByVal [error] As Entity.SessionError)
        MessageBox.Show([String].Format("Status {0}: {1}", [error].Status.ToString(), [error].Description), "Ecodex UniTest")
    End Sub

   
    Private Sub guardarLog(ByVal fileName As String, ByVal [error] As String)
        Dim lsName As New StringBuilder(Path.GetFileName(fileName))
        Dim lsDir As New StringBuilder(Path.GetDirectoryName(fileName))
        Dim lsExt As New StringBuilder(Path.GetExtension(fileName).ToUpper())
        Dim lsOutputFile As New StringBuilder(String.Format("{0}\{1}{2}{3}", lsDir, lsName, "_error", ".txt"))

        Using loSW As New StreamWriter(lsOutputFile.ToString(), True, Encoding.UTF8)
            loSW.Write([error])
        End Using
        lstDestination.Items.Add(lsOutputFile.ToString())
    End Sub

    Private Sub lstDestination_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstDestination.DoubleClick
        Dim psi As New ProcessStartInfo() With { _
 .FileName = lstDestination.SelectedItem.ToString() _
}
        Using process As New Process() With { _
         .StartInfo = psi _
        }
            process.Start()
        End Using
    End Sub

    Private Shared Function retenciones(ByVal XML As String) As String
        Dim xmlRetencion As String = String.Empty
        Dim Certificado As String = String.Empty
        Dim noCertificado As String = String.Empty
        Try
            Dim retencion As Retenciones = New Retenciones()
            retencion = GeneradorSello.Deserialization(retencion, GetType(Retenciones), XML)

            retencion.FechaExp = Date.Now.ToString("yyyy-MM-ddThh:mm:sszzz")
            xmlRetencion = GeneradorSello.SerializeRetencion(retencion, GetType(Retenciones))

            retencion.Sello = GeneradorSello.stampInvoice(xmlRetencion, Certificado, noCertificado)
            retencion.Cert = Certificado
            retencion.NumCert = noCertificado

            xmlRetencion = GeneradorSello.SerializeRetencion(retencion, GetType(Retenciones))
        Catch ex As Exception
            Throw ex
        End Try
        Return xmlRetencion
    End Function

    Private Shared Function cfdiComprobante(ByVal XML As String) As String
        Dim xmlCfdi As String = String.Empty
        Dim Certificado As String = String.Empty
        Dim noCertificado As String = String.Empty
        Try
            Dim cfdi As Comprobante = New Comprobante()
            cfdi = GeneradorSello.Deserialization(cfdi, GetType(Comprobante), XML)

            cfdi.fecha = Date.Now
            xmlCfdi = GeneradorSello.Serialize32(cfdi, GetType(Comprobante))

            cfdi.sello = GeneradorSello.stampInvoice(xmlCfdi, Certificado, noCertificado)
            cfdi.certificado = Certificado
            cfdi.noCertificado = noCertificado

            xmlCfdi = GeneradorSello.Serialize32(cfdi, GetType(Comprobante))
        Catch ex As Exception
            Throw ex
        End Try
        Return xmlCfdi
    End Function


End Class